package com.ts.api.module.match.plan.internal.distribute.handler;

import com.gitee.apanlh.util.base.StringUtils;
import com.gitee.apanlh.util.log.Log;
import com.gitee.apanlh.util.reflection.CopyUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.productflow.ProductApplyFlowStatusEnum;
import com.ts.api.common.util.ExceptionUtils;
import com.ts.api.module.api.convert.core.handler.ApiConvertHandler;
import com.ts.api.module.api.convert.core.http.client.ApiHttpMessage;
import com.ts.api.module.api.convert.plan.context.ApiPlanConvertContext;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistribute;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeField;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributePost;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeResult;
import com.ts.api.module.match.plan.internal.distribute.strategy.PlanDistributeStrategy;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.service.ProductApplyFlowService;
import com.ts.api.module.product.service.ProductPlanTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *  计划分发策略处理器
 *
 *  @author Pan
 */
@Service
public class PlanDistributeHandler {

    @Autowired
    private ProductPlanTypeService productPlanTypeService;
    @Autowired
    private ProductApplyFlowService productApplyFlowService;
    @Autowired
    private ApiPlanConvertContext apiPlanConvertContext;

    public PlanDistributeResult preHandle(PlanDistribute planDistribute, PlanDistributeStrategy<ApiConvertHandler> context) {
        PlanDistributeResult planDistributeResult = context.preValidate(planDistribute);
        planDistributeResult.setReqId(planDistribute.getReqId());
        return planDistributeResult;
    }

    public PlanDistributeResult distributeHandle(PlanDistribute planDistribute, PlanDistributeStrategy<ApiConvertHandler> context) {
        PlanDistributeResult planDistributeResult = context.distribute(planDistribute);
        planDistributeResult.setReqId(planDistribute.getReqId());
        return planDistributeResult;
    }

    public PlanDistributeField parseResponseHandle(PlanDistribute planDistribute, ApiHttpMessage apiHttpMessage, PlanDistributeStrategy<ApiConvertHandler> context) {
        ProductPO productPO = planDistribute.getProductPO();
        ProductPlanPO productPlanPO = planDistribute.getProductPlanPO();
        ProductApplyFlowPO currentDistributeFlow = planDistribute.getCurrentDistributeFlow();

        try {
            //  本地计划
            if (productPlanTypeService.hasLocalProduct(productPO)) {
                //  插入预匹配成功
                ProductApplyFlowPO copy = CopyUtils.copy(currentDistributeFlow, ProductApplyFlowPO.class);
                copy.setBizStatus("1");
                copy.setStatus(ProductApplyFlowStatusEnum.DATA_EXCHANGE_PRE_SUC.getType());
                productApplyFlowService.insert(copy, true);
                return context.parseResponse(planDistribute, apiHttpMessage, null);
            }

            //  非本地计划获取解析器
            ApiConvertHandler convertHandler = apiPlanConvertContext.getPlanHandler(productPO, productPlanPO);
            PlanDistributeField planDistributeField = context.parseResponse(planDistribute, apiHttpMessage, convertHandler);

            //  记录解析字段过程-业务异常
            String bizErrorMsg = planDistributeField.getBizErrorMsg();
            ProductApplyFlowStatusEnum bizErrorType = planDistributeField.getBizErrorType();
            if (ValidParam.isNotEmpty(bizErrorMsg) && ValidParam.isNotNull(bizErrorType)) {
                currentDistributeFlow.setStatus(bizErrorType.getType());
                currentDistributeFlow.setExceptionMsg(bizErrorMsg);
                productApplyFlowService.insert(currentDistributeFlow, true);
            }
            return planDistributeField;
        } catch (Exception e) {
            //  记录错误异常
            String stackTrace = ExceptionUtils.getStackTrace(e);
            currentDistributeFlow.setExceptionMsg(StringUtils.format("主体id:{},计划id:{},解析下游时出现异常:{}", productPO.getId(), productPlanPO.getId(), e.getMessage()));
            currentDistributeFlow.setStackMsg(stackTrace);
            currentDistributeFlow.setStatus(ProductApplyFlowStatusEnum.DATA_EXCHANGE_EXCEPTION.getType());
            productApplyFlowService.insert(currentDistributeFlow, true);
            Log.get().error("主体id:{},计划id:{},解析下游时出现异常:{}", productPO.getId(), productPlanPO.getId(), e.getMessage(), e);
            return PlanDistributeField.ofFail(e.getMessage());
        }
    }

    public PlanDistributeResult postHandle(PlanDistributePost planDistributePost, PlanDistributeStrategy<ApiConvertHandler> context) {
        PlanDistribute planDistribute = planDistributePost.getPlanDistribute();
        ProductPO productPO = planDistribute.getProductPO();
        ProductPlanPO productPlanPO = planDistribute.getProductPlanPO();
        ProductApplyFlowPO currentDistributeFlow = planDistribute.getCurrentDistributeFlow();

        try {
            //  分发结果处理
            PlanDistributeResult planDistributeResult = context.post(planDistributePost);
            planDistributeResult.setReqId(planDistributePost.getReqId());

            //  记录最终处理-业务异常
            String bizErrorMsg = planDistributeResult.getBizErrorMsg();
            ProductApplyFlowStatusEnum bizErrorType = planDistributeResult.getBizErrorType();
            if (ValidParam.isNotEmpty(bizErrorMsg)) {
                currentDistributeFlow.setStatus(bizErrorType.getType());
                currentDistributeFlow.setExceptionMsg(bizErrorMsg);
                productApplyFlowService.insert(currentDistributeFlow, true);
                return planDistributeResult;
            }

            //  API机构计划增加预匹配成功
            if (productPlanTypeService.hasApiOrgPlan(productPO, productPlanPO)) {
                ProductApplyFlowPO copy = CopyUtils.copy(currentDistributeFlow, ProductApplyFlowPO.class);
                copy.setBizStatus("1");
                copy.setStatus(ProductApplyFlowStatusEnum.DATA_EXCHANGE_PRE_SUC.getType());
                productApplyFlowService.insert(copy, true);
            }
            return planDistributeResult;
        } catch (Exception e) {
            String stackTrace = ExceptionUtils.getStackTrace(e);
            currentDistributeFlow.setExceptionMsg(StringUtils.format("主体id:{},计划id:{},后置处理时出现异常:{}", productPO.getId(), productPlanPO.getId(), e.getMessage()));
            currentDistributeFlow.setStackMsg(stackTrace);
            currentDistributeFlow.setStatus(ProductApplyFlowStatusEnum.DATA_EXCHANGE_EXCEPTION.getType());
            productApplyFlowService.insert(currentDistributeFlow, true);
            Log.get().error("主体id:{},计划id:{},解析下游时出现异常:{}", productPO.getId(), productPlanPO.getId(), e.getMessage(), e);
            return PlanDistributeResult.ofFail(e.getMessage());
        }
    }
}
